package BusinessLogic;

import Persistance.Configuration;
import Persistance.MySqlUtilityManagment;
import Persistance.FilteringAlgorithmContext;
import Persistance.CollaborationAlgo;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

import java.io.*;

import Domain.KMeansStrategy;

/**
 * Singeltone calss that manage all he data in the system using 3 handlersL
 *  MovieHandler ,UserHandler ,RecommendationHandler
 * it also has the access to the lower level of MYSqlUtilityManagment
 */
public class DataController implements Serializable {

    private static DataController m_instance = null;

    private MovieHandler            m_movieHandler;
    private UserHandler             m_userHandler;
    private RecommendationHandler   m_recommendationHandler;
    private MySqlUtilityManagment   m_sql;

    private int                     m_algoParam;

    static Logger logger            = Logger.getLogger("MovieSystem.BussinessLogic.DataController");

    private int m_listLength;
    private int m_minimumRecommendations;

    private DataController(){
        init("config.ini");
        m_sql.connect();
        m_recommendationHandler = new RecommendationHandler(m_sql,m_algoParam);
        m_movieHandler          = new MovieHandler(m_sql);
        m_userHandler           = new UserHandler(m_sql);
    }

    private void init(String filename){
        Configuration cfg = new Configuration();
        try {
            cfg.initProperties(filename);
        }
        catch (IOException e) {
            logger.info("Cannot load configuration file. using defaults.");
        }
        m_sql = new MySqlUtilityManagment(
            cfg.getMySqlAddress(),cfg.getMySqlPort(),cfg.getMySqlSchema(),
            cfg.getMySqlUser(),cfg.getMySqlPassword());
        setLogger(cfg.getLoggerFilename(), cfg.getLoggerPattern(), cfg.getLoggerLevel());
        m_listLength = cfg.getListLength();
        m_minimumRecommendations = cfg.getMinimumRecommendations();
        m_algoParam = cfg.getAlgoParam();
    }

    private static void setLogger(String filename,String pattern,String level){
        Logger movieSystemLogger = Logger.getLogger("MovieSystem");
        PatternLayout layout = new PatternLayout(pattern);
        FileAppender appender;
        try {
            appender = new FileAppender(layout, filename ,false);
        }
        catch(Exception e) {
            // logger is disabled
            return;
        }
        movieSystemLogger.addAppender(appender);
        movieSystemLogger.setLevel(Level.toLevel(level));
        logger.info("Logger started");
    }

    public static DataController getInstance(){
        if(m_instance == null){
            m_instance = new DataController();
        }
        return m_instance;
    }


    // ****************   Getters ******************************************
    
    public MovieHandler getMovieHandler() {
        return m_movieHandler;
    }

    public RecommendationHandler getRecommendationHandler() {
        return m_recommendationHandler;
    }

    public UserHandler getUserHandler() {
        return m_userHandler;
    }

    public int getMinimumRecommendations() {
        return m_minimumRecommendations;
    }

    public int getListLength() {
        return m_listLength;
    }
}
